/**
 * \file PluginManager.h
 * \brief PluginManager declaration class
 * \author Edouard ROGE
 * \date 16 Mars 2013
 */
#ifndef _PLUGINMANAGER_
#define _PLUGINMANAGER_

#include "Plugin.h"
#include "Core/Array/Array.h"
#include "Core/Pattern/Singleton.h"
#include "Core/Error/Error.h"

/**
 * \class PluginManager
 * \brief Load / unload plug-ins
 */
class PluginManager : public Singleton<PluginManager>
{
public:
	/**
	 * \fn PluginManager();
	 * \brief Default constructor
	 */
	PluginManager();
	
	/**
	 * \fn virtual ~PluginManager();
	 * \brief Destructor
	 */
	virtual ~PluginManager();

	/**
	* \fn template <class T> error RegisterPlugin(Plugin::Type _ePluginType, const String & _strPluginName);
	 * \param _ePluginType Plug-in type
	 * \param _strPluginName Path of the plug-in to load
	 * \return Error if occurs
	 * \brief Register and load a plug-in to the plug-in manager
	 */
	template <class T> error RegisterPlugin(Plugin::Type _ePluginType, const String & _strPluginName);
	
	/**
	 * \fn error UnregisterPlugin(Plugin::Type _ePluginType);
	 * \param _ePluginType Type of the plug-in to unload
	 * \return Error if occurs
	 * \brief Unregister and unload a plug-in from the plug-in manager
	 */
	error UnregisterPlugin(Plugin::Type _ePluginType);

	/**
	 * \fn Plugin * GetPlugin(Plugin::Type _ePluginType) const;
	 * \param _ePluginType type of plugin to retrieve from
	 * \return Plugin corresponding to the type
	 * \biref Get the plugin according to its type
	 */
	Plugin * GetPlugin(Plugin::Type _ePluginType) const;
	
	/**
	 * \fn PluginInterface * GetPluginInterface(Plugin::Type _ePluginType) const;
	 * \param _ePluginType type of plugin to retrieve from
	 * \return PluginInterface corresponding to the type
	 * \biref Get the plugin interface according to its type
	 */
	PluginInterface * GetPluginInterface(Plugin::Type _ePluginType) const;

private:

	/** List of available plug-ins */
	Array<Plugin*> m_Plugins;
};

#endif // _PLUGINMANAGER_
